{--
nome: fernando lima rivas
matricula: 2750068
discplina: elc117 - paradigmas de programacao
professora: andrea schwertner charao
avaliacao: t2 - lista de exercicios haskell
-}

module Main where

import Data.Char -- questao 10

{--
1. Escreva uma função recursiva strSizes :: [String] -> [Int], que receba uma lista de strings e 
retorne uma lista com os tamanhos dessas strings. Exemplos de uso da função:
> strSizes []
[]
> strSizes ["abra","ca","dabra"]
[4,2,5]
--}
{--
strSizes :: [String] -> [Int]
strSizes [] = []
strSizes (x:xs) = length x : strSizes xs
--}

{--
2. Crie uma função recursiva charFound :: Char -> String -> Bool, que indique se o primeiro 
argumento está contido na lista passada como segundo argumento. Exemplos de uso da função:
> charFound 'a' ""
False
> charFound 'a' "uau"
True
--}
{--
charFound :: Char -> String -> Bool
charFound _ [] = False
charFound a (x:xs)
    | a == x = True
    | otherwise = charFound a xs
--}

{--
3. Defina uma função recursiva removeSpaces :: String -> String, que receba uma string e retorne 
uma string equivalente, sem espaços em branco. Exemplo de uso da função:
> removeSpaces "abra ca dabra"
"abracadabra"
--}
{--
removeSpaces :: String -> String
removeSpaces [] = []
removeSpaces (x:xs)
    | x == ' ' = removeSpaces xs
    | otherwise = x : removeSpaces xs
--}

{--
4. Escreva uma função htmlLink :: (String, String) -> String, que receba uma tupla contendo 
um nome e uma URL e retorne esses dados em uma string formatada como um link HTML.
Exemplo de uso da função:
> htmlLink ("Inf", "http://www.inf.ufsm.br")
"<A HREF=\"http://www.inf.ufsm.br\">Inf</A>"
--}
-- htmlLink :: (String, String) -> String
-- htmlLink (x,y) = ("<A HREF =\"") ++ snd(x,y) ++ "\">" ++ fst(x,y) ++ "</A>"
-- PS: \" representa \

{--
5. Crie uma função recursiva htmlListItems :: [String] -> [String], que receba uma lista de 
strings e retorne outra lista contendo as strings formatadas como itens de lista em HTML.
Exemplo de uso da função:
> htmlListItems ["abra", "ca", "dabra"]
["<LI>abra</LI>", "<LI>ca</LI>", "<LI>dabra</LI>"]
--}
-- htmlListItems :: [String] -> [String]
-- htmlListItems [] = []
-- htmlListItems (x:xs) = ("<LI>" ++ x ++ "</LI>") : htmlListItems xs 

{--
6. Escreva uma função recursiva maiorElem :: [Int] -> Int que retorne o
maior número contido na lista passada como argumento. Obs.: Esta
função não é definida para listas vazias, portanto suponha que a lista
passada como argumento possua no mínimo um elemento.
Exemplos de uso da função:
> maiorElem [6]
6
> maiorElem [4,5,1,8,3,1]
8
--}
-- maiorElem :: [Int] -> Int
-- maiorElem [] = 0
-- maiorElem (x:xs) = max x (maiorElem xs)

{--
7. Defina uma função recursiva intervalo :: Int -> Int -> Int -> [Int], que receba 3 inteiros a, b, p 
e retorne uma lista contendo números no intervalo [a..b], com passo p. Exemplos de uso da função:
> intervalo 1 4 1
[1,2,3,4]
> intervalo 1 1 1
[1]
> intervalo 1 6 2
[1,3,5]
--}
-- lembrar d PA (progressao aritmetica)
-- an = a1 + (n - 1)*r
-- intervalo a b p = [a,a+p..b]
-- ou
-- intervalo a b p = [a+p | a <- [a..b]]
-- ou
-- intervalo :: Int -> Int -> Int -> [Int]
-- intervalo a b p = a : if (a+p <= b) then intervalo (a+p) b p else []

{--
8. Escreva uma função recursiva mapfxy :: [(Int,Int)] -> [Int], que receba uma lista de tuplas de 
forma (x,y) e retorne uma lista contendo o valor de 2*x + y para cada tupla. Exemplo de uso da função:
> mapfxy [(2,1),(3,2),(4,3)]
[5,8,11]
--}
-- mapfxy :: [(Int,Int)] -> [Int]
-- mapfxy [] = []
-- mapfxy (x:xs) = 2*(fst x) + snd x : mapfxy xs

{--
9. Escreva outra versão da função mapfxy, desta vez definindo e usando
uma função auxiliar auxFunc :: (Int,Int) -> Int.
--}
-- mapfxy :: [(Int,Int)] -> [Int]
-- mapfxy [] = []
-- mapfxy (x:xs) = auxFunc x : mapfxy xs

-- auxFunc :: (Int,Int) -> Int
-- auxFunc (a,b) = 2*fst (a,b) + snd (a,b)

{--
10.Defina uma função hex2dec :: [Char] -> Int, que receba uma string representando um número 
hexadecimal e retorne o inteiro correspondente. Obs.: Você pode considerar que a string sempre será
válida, isto é, não é necessário testar se a string realmente representa um número hexadecimal.
Exemplos de uso da função:
> hex2dec "A"
10
> hex2dec "10"
16
> hex2dec "F"
15
> hex2dec "11"
17
--}
-- hex2dec :: [Char] -> Int
-- hex2dec [] = 0
-- hex2dec (x:xs) = (digitToInt x)*16^(length (x:xs)-1) + hex2dec xs

{--
11.Defina uma função recursiva genérica combina :: [a] -> [b] -> [(a,b)], que receba 2 listas do 
mesmo tamanho e combine-as em uma lista de tuplas, conforme os exemplos abaixo:
> combina [1,2] [10,20]
[(1,10),(2,20)]
> combina [1,2,3] ['a','b','c']
[(1,'a'),(2,'b'),(3,'c')]
--}
-- combina :: [a] -> [b] -> [(a,b)]
-- combina _ [] = []
-- combina [] _ = []
-- combina [] [] = []
-- combina (x:xs) (y:ys) = (x,y):combina xs ys

{--
12.Defina uma função intersect :: [Int] -> [Int] -> [Int] que retorne a interseção entre duas 
listas fornecidas. Exemplos de uso da função:
> intersect [1,2] [3,4,5]
[]
> intersect [1,2] [3,1,4,3,5]
[1]
> intersect [1,2] [3,1,4,2,5]
[1,2]
> intersect [1,2] [3,1,4,2,5,2]
[1,2]
--}
-- intersect :: [Int] -> [Int] -> [Int]
-- intersect [] [] = []
-- intersect _  [] = []
-- intersect [] _  = []
-- intersect (x:xs) (y:ys)
--     | intersectAux x ys == True = x : intersect xs ys
--     | otherwise = []

-- verifica se o elemento dado esta na lista
-- intersectAux :: Int -> [Int] -> Bool
-- intersectAux _ [] = False
-- intersectAux x (y:ys)
--     | x == y    = True
--     | otherwise = intersectAux x ys

{--
13.Existe uma biblioteca em Haskell chamada Prelude, que é importada por default e contém as funções 
pré-definidas mais usadas. Um resumo das funções desta biblioteca pode ser encontrado neste endereço:
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html
Estude 4 funções desta biblioteca que operam sobre listas (List operations) e forneça exemplos de uso 
dessas funções. Os exemplos podem ser execuções no interpretador e/ou definições de novas funções que 
reusam funções do Prelude. Quanto mais originais os exemplos, maior a nota.
--}
-- comando 1: takewhile
-- takeWhile :: (a -> Bool) -> [a] -> [a]
-- retorna uma lista com os elementos que concordam com a condicao
-- exemplos:
-- takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2]
-- takeWhile (< 9) [1,2,3] == [1,2,3]
-- takeWhile (< 0) [1,2,3] == []

-- comando 2: dropWhile
-- dropWhile :: (a -> Bool) -> [a] -> [a]
-- retorna uma lista com os elementos que nao concordam com a condicao
-- exemplos:
-- dropWhile (< 3) [1,2,3,4,5,1,2,3] == [3,4,5,1,2,3]
-- dropWhile (< 9) [1,2,3] == []
-- dropWhile (< 0) [1,2,3] == [1,2,3]

-- comando 3: span
-- span :: (a -> Bool) -> [a] -> ([a], [a])
-- retorna uma tupla onde fst equivale a takeWhile e snd equivale a dropWhile
-- exemplos:
-- span (< 3) [1,2,3,4,1,2,3,4] == ([1,2],[3,4,1,2,3,4])
-- span (< 9) [1,2,3] == ([1,2,3],[])
-- span (< 0) [1,2,3] == ([],[1,2,3])

-- comando 4: zip
-- retorna uma lista de tuplas somente com os elementos correspondentes
-- zip :: [a] -> [b] -> [(a,b)]
-- zip [] ys = []
-- zip (x:xs) [] = []
-- zip (x:xs) (y:ys) = (x,y) : zip xs ys
-- exemplos:
-- zip ['a','b','c'] [1,2,3,4]
-- [('a',1), ('b',2), ('c',3)]
-- zip ['a','b','c','d'] [1,2]
-- [('a',1), ('b',2)]

-- comando 5: zipWith
-- recebe uma função e duas listas como parâmetros e então junta as duas listas aplicando a função 
-- entre os elementos correspondentes
-- zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]  
-- zipWith' _ [] _ = []  
-- zipWith' _ _ [] = []  
-- zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys 
-- exemplos:
-- > zipWith' (+) [4,2,5,6] [2,6,2,3]  
-- [6,8,7,9]  
-- > zipWith' max [6,3,2,1] [7,3,1,5]  
-- [7,3,2,5]